package com.bkgy.controller.tpdol3data.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.commom.model.Temp;
import com.bkgy.controller.repOutput.entity.RepOutput;
import com.bkgy.controller.repOutput.service.IRepOutputService;
import com.bkgy.controller.shutdowndetails.entity.dto.TbDowntimeTcm2280Dto;
import com.bkgy.controller.shutdowndetails.entity.tbDowntimeCal1630;
import com.bkgy.controller.shutdowndetails.entity.tbDowntimeCal2150;
import com.bkgy.controller.shutdowndetails.entity.tbDowntimeCgl1870;
import com.bkgy.controller.shutdowndetails.service.ShutdownService;
import com.bkgy.controller.tPdiDataL3Tcm2280.entity.RepTcmOutputHour;
import com.bkgy.controller.tPdiDataL3Tcm2280.entity.TbTcm2280RepSpe;
import com.bkgy.controller.tcmReport.entity.RepTcmOutputPlanAct;
import com.bkgy.controller.tcmReport.service.IRepTcmOutputPlanActService;
import com.bkgy.controller.tpdol3data.dao.TPdoL3Tcm2280Dao;
import com.bkgy.controller.tpdol3data.entity.TPdoDataL3Tcm2280;
import com.bkgy.controller.tpdol3data.entity.TpdoL3;
import com.bkgy.controller.tpdol3data.entity.TpdoL3TcmCrew;
import com.bkgy.controller.tpdol3data.entity.TpdoL3TcmYield;
import com.bkgy.controller.tpdol3data.entity.dto.*;
import com.bkgy.controller.tpdol3data.service.ITPdoL3Tcm2280Service;
import com.bkgy.controller.tpdol3data.service.ITbTcm2280DayRepService;
import com.bkgy.controller.tpdol3data.service.ITbTcm2280RepSpeService;
import com.bkgy.sys.common.constant.CommonConstant;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class
TPdoL3Tcm2280Servicempl extends ServiceImpl<TPdoL3Tcm2280Dao, TPdoDataL3Tcm2280> implements ITPdoL3Tcm2280Service {
    private final TPdoL3Tcm2280Dao mapper;
    private final ITbTcm2280DayRepService repOutputHourService;
    private final ITbTcm2280RepSpeService repSpeService;
    private final ShutdownService downTimeService;
    private final IRepTcmOutputPlanActService repPlanActService;
    private final IRepOutputService repOutputService;

    @Override
    public List<Temp> selectPage(int rollNum) {
        return mapper.selectLastRoll(rollNum);
    }

    @Override
    public ResultData<TpdoL3Res> findL3Data() {
        TpdoL3Res l3 = new TpdoL3Res();
        List<String> clist = new ArrayList<>();
        clist.add("酸轧");
        clist.add("连退1630");
        clist.add("连退2150");
        clist.add("镀锌1870");
        clist.add("重卷");
        clist.add("缴库量");
        l3.setCategory(clist);

        String startDay = thisMonthFirstDay();
        String endDay = nextMonthFirstDay();
        List<BigDecimal> tarList = new ArrayList<>();
        List<BigDecimal> actList = new ArrayList<>();
        TpdoL3 tp0 = repOutputHourService.findL3Data2280(startDay, endDay);
        tarList.add(tp0 == null ? BigDecimal.ZERO : tp0.getTarget());
        actList.add(tp0 == null ? BigDecimal.ZERO : tp0.getActual());
        TpdoL3 tp1 = mapper.findL3Data1630(startDay, endDay);
        tarList.add(tp1 == null ? BigDecimal.ZERO : tp1.getTarget());
        actList.add(tp1 == null ? BigDecimal.ZERO : tp1.getActual());
        TpdoL3 tp2 = mapper.findL3Data2150(startDay, endDay);
        tarList.add(tp2 == null ? BigDecimal.ZERO : tp2.getTarget());
        actList.add(tp2 == null ? BigDecimal.ZERO : tp2.getActual());
        TpdoL3 tp3 = mapper.findL3Data1870(startDay, endDay);
        tarList.add(tp3 == null ? BigDecimal.ZERO : tp3.getTarget());
        actList.add(tp3 == null ? BigDecimal.ZERO : tp3.getActual());

        //TODO 重卷待处理
        tarList.add(BigDecimal.valueOf(0));
        actList.add(BigDecimal.valueOf(0));
        //TODO 缴库量待处理
        tarList.add(BigDecimal.valueOf(0));
        actList.add(BigDecimal.valueOf(0));

        l3.setTarget(tarList);
        l3.setActual(actList);
        return ResultData.ResultDataSuccess(l3);
    }

    @Override
    public ResultData<TpdoL3Res> findL3QuaData() {
        TpdoL3Res l3 = new TpdoL3Res();
        List<String> clist = new ArrayList<>();
        clist.add("酸轧2280");
        clist.add("连退2150");
        clist.add("连退1630");
        clist.add("镀锌1870");
        clist.add("重卷机组");
        l3.setCategory(clist);

        List<BigDecimal> tarList = new ArrayList<>();
        List<BigDecimal> actList = new ArrayList<>();
        tarList.add(BigDecimal.valueOf(70));
        tarList.add(BigDecimal.valueOf(40));
        tarList.add(BigDecimal.valueOf(32));
        tarList.add(BigDecimal.valueOf(30));
        tarList.add(BigDecimal.valueOf(10));

        actList.add(BigDecimal.valueOf(70));
        actList.add(BigDecimal.valueOf(40));
        actList.add(BigDecimal.valueOf(32));
        actList.add(BigDecimal.valueOf(30));
        actList.add(BigDecimal.valueOf(10));
        l3.setTarget(tarList);
        l3.setActual(actList);

        return ResultData.ResultDataSuccess(l3);
    }

    @Override
    public ResultData<TpdoL3Res> findL3SucData() {
        TpdoL3Res l3 = new TpdoL3Res();
        List<String> clist = new ArrayList<>();
        clist.add("作业区");
        clist.add("酸轧2280");
        clist.add("连退2150");
        clist.add("连退1630");
        clist.add("镀锌1870");
        clist.add("重卷机组");
        l3.setCategory(clist);

        String startDay = thisMonthFirstDay();
        String endDay = nextMonthFirstDay();
        List<BigDecimal> tarList = new ArrayList<>();
        List<BigDecimal> actList = new ArrayList<>();
        //TODO 作业区数据不明
        tarList.add(BigDecimal.ZERO);
        actList.add(BigDecimal.ZERO);
        //酸轧成材率
        TpdoL3TcmYield yield2280 = mapper.findYield2280Data(startDay, endDay);
        tarList.add(yield2280.getTarget());
        actList.add(yield2280.getActual());
        //连退2150
        TpdoL3TcmYield yield2150 = mapper.findYield2150Data(startDay, endDay);
        tarList.add(yield2150.getTarget());
        actList.add(yield2150.getActual());
        //连退1630
        TpdoL3TcmYield yield1630 = mapper.findYield1630Data(startDay, endDay);
        tarList.add(yield1630.getTarget());
        actList.add(yield1630.getActual());
        //镀锌1870
        TpdoL3TcmYield yield1870 = mapper.findYield1870Data(startDay, endDay);
        tarList.add(yield1870.getTarget());
        actList.add(yield1870.getActual());

        //TODO 重卷机组数据不明
        tarList.add(BigDecimal.ZERO);
        actList.add(BigDecimal.ZERO);

        l3.setTarget(tarList);
        l3.setActual(actList);

        return ResultData.ResultDataSuccess(l3);
    }

    /**
     * 本月第一天
     *
     * @return 格式yyyyMM01
     */
    private String thisMonthFirstDay() {
        return thisMonthFirstDay("yyyyMM01");
    }

    private String thisMonthFirstDay(String format) {
        return DateUtil.getDateToString(new Date(), format);
    }

    private String tenDaysAgo() {
        return tenDaysAgo("yyyyMMdd");
    }

    private String tenDaysAgo(String format) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        //向前10天
        cal.add(Calendar.DAY_OF_MONTH, -10);
        return DateUtil.getDateToString(cal.getTime(), format);
    }

    //下月第一天
    private String nextMonthFirstDay() {
        return nextMonthFirstDay("yyyyMM01");
    }

    private String nextMonthFirstDay(String format) {
        SimpleDateFormat f = new SimpleDateFormat(format);
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 1);
        return f.format(cal.getTime());
    }

    @Override
    public ResultData<TpdoL3Res> findL3Spedata() {
        TpdoL3Res l3 = new TpdoL3Res();
        List<String> clist = new ArrayList<>();
        clist.add("高强钢");
        clist.add("宽料");
        clist.add("薄料");
        clist.add("外板");
        l3.setCategory(clist);

        List<BigDecimal> actList = new ArrayList<>();
        LambdaQueryWrapper<TbTcm2280RepSpe> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(TbTcm2280RepSpe::getShijian, thisMonthFirstDay()).lt(TbTcm2280RepSpe::getShijian, nextMonthFirstDay());
        List<TbTcm2280RepSpe> gaoqiangList = repSpeService.list(wrapper);
        BigDecimal sumGaoqiang = BigDecimal.ZERO;
        BigDecimal sumKuan = BigDecimal.ZERO;
        BigDecimal sumBo = BigDecimal.ZERO;
        BigDecimal sumWai = BigDecimal.ZERO;
        for (TbTcm2280RepSpe spe : gaoqiangList) {
            sumGaoqiang = sumGaoqiang.add(spe.getGaoqiang());
            sumKuan = sumKuan.add(spe.getKuanliao());
            sumBo = sumBo.add(spe.getBoliao());
            sumWai = sumWai.add(spe.getWaiban());
        }
        actList.add(sumGaoqiang);
        actList.add(sumKuan);
        actList.add(sumBo);
        actList.add(sumWai);
        l3.setActual(actList);
        //TODO
        List<BigDecimal> targetList = new ArrayList<>();
        targetList.add(BigDecimal.ZERO);
        targetList.add(BigDecimal.ZERO);
        targetList.add(BigDecimal.ZERO);
        targetList.add(BigDecimal.ZERO);
        l3.setTarget(targetList);

        return ResultData.ResultDataSuccess(l3);
    }

    @Override
    public ResultData<TpdoL3ProfitRes> findL3ProfitData() {
        TpdoL3ProfitRes l3 = new TpdoL3ProfitRes();
        List<String> clist = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int month = cal.get(Calendar.MONTH) + 1;
        for (int i = 3; i >= 0; i--) {
            clist.add((month - i) + "月份");
        }
        l3.setCategory(clist);

        List<BigDecimal> qicheList = new ArrayList<>();
        qicheList.add(BigDecimal.valueOf(4.3));
        qicheList.add(BigDecimal.valueOf(2.5));
        qicheList.add(BigDecimal.valueOf(3.5));
        qicheList.add(BigDecimal.valueOf(4.5));
        l3.setQiche(qicheList);

        List<BigDecimal> lengyingList = new ArrayList<>();
        lengyingList.add(BigDecimal.valueOf(2.4));
        lengyingList.add(BigDecimal.valueOf(4.4));
        lengyingList.add(BigDecimal.valueOf(1.8));
        lengyingList.add(BigDecimal.valueOf(2.8));
        l3.setLengying(lengyingList);

        List<BigDecimal> gaoqiangList = new ArrayList<>();
        gaoqiangList.add(BigDecimal.valueOf(2));
        gaoqiangList.add(BigDecimal.valueOf(2));
        gaoqiangList.add(BigDecimal.valueOf(3));
        gaoqiangList.add(BigDecimal.valueOf(5));
        l3.setGaoqiang(gaoqiangList);

        return ResultData.ResultDataSuccess(l3);
    }

    @Override
    public ResultData<TpdoL3ImpRes> findL3ImpData() {
        TpdoL3ImpRes l3 = new TpdoL3ImpRes();
        List<String> clist = new ArrayList<>();
        clist.add("甲");
        clist.add("乙");
        clist.add("丙");
        clist.add("丁");
        l3.setCategory(clist);

        LambdaQueryWrapper<TbTcm2280RepSpe> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(TbTcm2280RepSpe::getShijian, thisMonthFirstDay()).lt(TbTcm2280RepSpe::getShijian, nextMonthFirstDay());
        List<TbTcm2280RepSpe> dbList = repSpeService.list(wrapper);
        Map<String, TbTcm2280RepSpe> map1 = new HashMap<>();
        for (TbTcm2280RepSpe spe : dbList) {
            String banzu = spe.getBanzu();
            if (map1.containsKey(banzu)) {
                TbTcm2280RepSpe s = map1.get(banzu);
                s.setGaoqiang(s.getGaoqiang().add(spe.getGaoqiang()));
                s.setKuanliao(s.getKuanliao().add(spe.getKuanliao()));
                s.setBoliao(s.getBoliao().add(spe.getBoliao()));
                s.setWaiban(s.getWaiban().add(spe.getWaiban()));
            } else {
                TbTcm2280RepSpe s = new TbTcm2280RepSpe();
                s.setGaoqiang(spe.getGaoqiang());
                s.setKuanliao(spe.getKuanliao());
                s.setBoliao(spe.getBoliao());
                s.setWaiban(spe.getWaiban());
                map1.put(banzu, s);
            }
        }
        List<BigDecimal> gaoqiangList = new ArrayList<>();
        List<BigDecimal> kuanliaoList = new ArrayList<>();
        List<BigDecimal> boliaoList = new ArrayList<>();
        List<BigDecimal> waibanList = new ArrayList<>();
        String[] arr = new String[]{"A", "B", "C", "D"};
        for (String str : arr) {
            if (map1.containsKey(str)) {
                TbTcm2280RepSpe s = map1.get(str);
                gaoqiangList.add(s.getGaoqiang());
                kuanliaoList.add(s.getKuanliao());
                boliaoList.add(s.getBoliao());
                waibanList.add(s.getWaiban());
            } else {
                gaoqiangList.add(BigDecimal.ZERO);
                kuanliaoList.add(BigDecimal.ZERO);
                boliaoList.add(BigDecimal.ZERO);
                waibanList.add(BigDecimal.ZERO);
            }
        }
        l3.setGaoqiang(gaoqiangList);
        l3.setKuanliao(kuanliaoList);
        l3.setBoliao(boliaoList);
        l3.setWaiban(waibanList);

        return ResultData.ResultDataSuccess(l3);
    }

    @Override
    public ResultData<TpdoL3Res> findL3LiyongData() {
        TpdoL3Res l3 = new TpdoL3Res();
        List<String> clist = new ArrayList<>();
        List<BigDecimal> targetList = new ArrayList<>();
        List<BigDecimal> actList = new ArrayList<>();
        List<BigDecimal> achiList = new ArrayList<>();
        BigDecimal tcm_capacity_day = BigDecimal.valueOf(Double.valueOf(CommonConstant.constMap.get("tcm_capacity_day")));
        List<TpdoL3> list = mapper.findL3LiyongData(tenDaysAgo(), nextMonthFirstDay());
        for (TpdoL3 l : list) {
            Date d = DateUtil.getStringToDate("yyyyMMdd", l.getShijian());
            clist.add(DateUtil.getDateToString(d, "MM/dd"));
            targetList.add(l.getTarget());
            actList.add(l.getActual());
            //产能利用率：日实际产量/6246
            achiList.add(l.getActual().divide(tcm_capacity_day, 4, BigDecimal.ROUND_HALF_UP));
        }
        l3.setCategory(clist);
        l3.setTarget(targetList);
        l3.setActual(actList);
        l3.setAchi(achiList);

        return ResultData.ResultDataSuccess(l3);
    }

    @Override
    public ResultData findCrewData() {
        List<TpdoL3TcmCrew> list = mapper.findCrewData(thisMonthFirstDay(), nextMonthFirstDay());
        return ResultData.ResultDataSuccess(list, list.size());
    }

    @Override
    public boolean buildSpecialSteel(Date date) {
        String startDay = DateUtil.getDateToString(date, "yyyyMMdd");
        String endDay = DateUtil.getDateToString(DateUtil.getAfterDate(date), "yyyyMMdd");
        Map<String, TbTcm2280RepSpe> map = new HashMap<>();
        QueryWrapper<TPdoDataL3Tcm2280> wrapper = new QueryWrapper();
        int strongSteel = Integer.parseInt(CommonConstant.constMap.get("strong_steel"));
        wrapper.ge("shiji.prod_end_time", startDay).lt("shiji.prod_end_time", endDay).ge("jihua.YS", strongSteel);
        //查询高强钢
        List<TpdoL3TcmCrew> gaoqiangList = mapper.findStrongSteel(wrapper);
        for (TpdoL3TcmCrew t : gaoqiangList) {
            TbTcm2280RepSpe spe;
            if (map.containsKey(t.getCrew())) {
                spe = map.get(t.getCrew());
                spe.setGaoqiang(spe.getGaoqiang().add(t.getActual()));
            } else {
                spe = new TbTcm2280RepSpe();
                spe.setShijian(startDay);
                spe.setBanzu(t.getCrew());
                spe.setGaoqiang(t.getActual());
                map.put(t.getCrew(), spe);
            }
        }
        //查询宽料
        QueryWrapper<TPdoDataL3Tcm2280> wrapper1 = new QueryWrapper();
        int widthSteel = Integer.parseInt(CommonConstant.constMap.get("width_steel"));
        wrapper1.ge("shiji.prod_end_time", startDay).lt("shiji.prod_end_time", endDay).ge("jihua.IN_MAT_WIDTH", widthSteel);
        List<TpdoL3TcmCrew> kuanliaoList = mapper.findEnWidthSteel(wrapper1);
        for (TpdoL3TcmCrew t : kuanliaoList) {
            TbTcm2280RepSpe spe;
            if (map.containsKey(t.getCrew())) {
                spe = map.get(t.getCrew());
                spe.setKuanliao(spe.getKuanliao().add(t.getActual()));
            } else {
                spe = new TbTcm2280RepSpe();
                spe.setShijian(startDay);
                spe.setBanzu(t.getCrew());
                spe.setKuanliao(t.getActual());
                map.put(t.getCrew(), spe);
            }
        }
        //查询薄料 WHERE prod_end_time &gt;= #{startDay} and prod_end_time &lt; #{endDay} and OUT_MAT_THK &lt;=0.7
        QueryWrapper<TPdoDataL3Tcm2280> wrapper2 = new QueryWrapper<>();
        float thickSteel = Float.parseFloat(CommonConstant.constMap.get("thick_steel"));
        wrapper2.ge("prod_end_time", startDay).lt("prod_end_time", endDay).le("OUT_MAT_THK", thickSteel);
        List<TpdoL3TcmCrew> boliaoList = mapper.findExThickSteel(wrapper2);
        for (TpdoL3TcmCrew t : boliaoList) {
            TbTcm2280RepSpe spe;
            if (map.containsKey(t.getCrew())) {
                spe = map.get(t.getCrew());
                spe.setBoliao(spe.getBoliao().add(t.getActual()));
            } else {
                spe = new TbTcm2280RepSpe();
                spe.setShijian(startDay);
                spe.setBanzu(t.getCrew());
                spe.setBoliao(t.getActual());
                map.put(t.getCrew(), spe);
            }
        }
        //查询外板，表面精度代码：50、51
        List<TpdoL3TcmCrew> waiList = mapper.findWaiSteel(startDay, endDay);
        for (TpdoL3TcmCrew t : waiList) {
            TbTcm2280RepSpe spe;
            if (map.containsKey(t.getCrew())) {
                spe = map.get(t.getCrew());
                spe.setWaiban(spe.getWaiban().add(t.getActual()));
            } else {
                spe = new TbTcm2280RepSpe();
                spe.setShijian(startDay);
                spe.setBanzu(t.getCrew());
                spe.setWaiban(t.getActual());
                map.put(t.getCrew(), spe);
            }
        }

        List<TbTcm2280RepSpe> list = new ArrayList<>();
        for (Map.Entry<String, TbTcm2280RepSpe> entry : map.entrySet()) {
            log.info("当日生产班组：{}", entry.getKey());
            list.add(entry.getValue());
        }
        if (list.isEmpty()) {
            log.info("{}当日无生产信息", startDay);
        } else repSpeService.saveBatch(list);
        return true;
    }

    @Override
    public ResultData<WorkRate> workRate() {
        List<WorkRate> list = new ArrayList<>();
        //本月经历的小时数
        String day1 = DateUtil.thisMonthFirstDay("yyyyMMdd");
        Date d1 = DateUtil.getStringToDate("yyyyMMdd", day1);
        Date d2 = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(d2);
        int month = cal.get(Calendar.MONTH) + 1;
        //本月总小时数
        BigDecimal totalHour = BigDecimal.valueOf((d2.getTime() - d1.getTime()) / (3600 * 1000));

        //查询酸轧停机时间
        String startTime = DateUtil.thisMonthFirstDay("yyyy-MM-dd");
        BigDecimal tcmDurationSum = BigDecimal.ZERO;
        List<TbDowntimeTcm2280Dto> tcm2280DownList = downTimeService.selectTcmDownTimeMonth(startTime);
        for (TbDowntimeTcm2280Dto tcm2280 : tcm2280DownList) {
            //处理跨月停机情况
            Calendar cal1 = Calendar.getInstance();
            Date startDate = DateUtil.getStringToDate("yyyy-MM-dd HH:mm:ss.SSS", tcm2280.getStopStartTime());
            cal1.setTime(startDate);
            int startMonth = cal1.get(Calendar.MONTH) + 1;
            Calendar cal2 = Calendar.getInstance();
            if (tcm2280.getStopEndTime() == null) continue;
            Date stopDate = DateUtil.getStringToDate("yyyy-MM-dd HH:mm:ss.SSS", tcm2280.getStopEndTime());
            cal2.setTime(stopDate);
            int endMonth = cal2.get(Calendar.MONTH) + 1;
            Integer duration = tcm2280.getDuration();
            //开始结束对应的日不等
            if (startMonth != endMonth) {
                //当日开始，下日结束
                if (month == startMonth) {
                    long timeInMillis2 = cal1.getTimeInMillis();
                    cal1.add(Calendar.DAY_OF_MONTH, 1);
                    cal1.set(Calendar.HOUR_OF_DAY, 0);
                    cal1.set(Calendar.MINUTE, 0);
                    cal1.set(Calendar.SECOND, 0);
                    cal1.set(Calendar.MILLISECOND, 0);
                    long difference = cal1.getTimeInMillis() - timeInMillis2;
                    duration = (int) (difference / 1000);
                } else {
                    long timeInMillis2 = cal2.getTimeInMillis();
                    cal2.set(Calendar.HOUR_OF_DAY, 0);
                    cal2.set(Calendar.MINUTE, 0);
                    cal2.set(Calendar.SECOND, 0);
                    cal2.set(Calendar.MILLISECOND, 0);
                    long difference = timeInMillis2 - cal2.getTimeInMillis();
                    duration = (int) (difference / 1000);
                }
            }
            tcmDurationSum = tcmDurationSum.add(BigDecimal.valueOf(duration));
        }
        BigDecimal tcmStopHour = tcmDurationSum.divide(BigDecimal.valueOf(3600), 1, BigDecimal.ROUND_HALF_UP);
        WorkRate w1 = new WorkRate();
        w1.setLineName("3#酸轧");
        w1.setStopHour(tcmStopHour);
        w1.setTotalHour(totalHour);
        w1.setRate(totalHour.subtract(tcmStopHour).multiply(BigDecimal.valueOf(100)).divide(totalHour, 2, BigDecimal.ROUND_HALF_UP));
        list.add(w1);

        BigDecimal cal1630DurationSum = BigDecimal.ZERO;
        List<tbDowntimeCal1630> cal1630DownList = downTimeService.selectCal1630DownTimeMonth(startTime);
        for (tbDowntimeCal1630 down : cal1630DownList) {
            //处理跨月停机情况
            Calendar cal1 = Calendar.getInstance();
            Date startDate = DateUtil.getStringToDate("yyyy-MM-dd HH:mm:ss.SSS", down.getStopStartTime());
            cal1.setTime(startDate);
            int startMonth = cal1.get(Calendar.MONTH) + 1;
            Calendar cal2 = Calendar.getInstance();
            Date stopDate = DateUtil.getStringToDate("yyyy-MM-dd HH:mm:ss.SSS", down.getStopEndTime());
            cal2.setTime(stopDate);
            int endMonth = cal2.get(Calendar.MONTH) + 1;
            Integer duration = down.getDuration();
            //开始结束对应的日不等
            if (startMonth != endMonth) {
                //当日开始，下日结束
                if (month == startMonth) {
                    long timeInMillis2 = cal1.getTimeInMillis();
                    cal1.add(Calendar.DAY_OF_MONTH, 1);
                    cal1.set(Calendar.HOUR_OF_DAY, 0);
                    cal1.set(Calendar.MINUTE, 0);
                    cal1.set(Calendar.SECOND, 0);
                    cal1.set(Calendar.MILLISECOND, 0);
                    long difference = cal1.getTimeInMillis() - timeInMillis2;
                    duration = (int) (difference / 1000);
                } else {
                    long timeInMillis2 = cal2.getTimeInMillis();
                    cal2.set(Calendar.HOUR_OF_DAY, 0);
                    cal2.set(Calendar.MINUTE, 0);
                    cal2.set(Calendar.SECOND, 0);
                    cal2.set(Calendar.MILLISECOND, 0);
                    long difference = timeInMillis2 - cal2.getTimeInMillis();
                    duration = (int) (difference / 1000);
                }
            }
            cal1630DurationSum = cal1630DurationSum.add(BigDecimal.valueOf(duration));
        }
        BigDecimal cal1630StopHour = cal1630DurationSum.divide(BigDecimal.valueOf(3600), 1, BigDecimal.ROUND_HALF_UP);
        WorkRate w2 = new WorkRate();
        w2.setLineName("2#连退");
        w2.setStopHour(cal1630StopHour);
        w2.setTotalHour(totalHour);
        w2.setRate(totalHour.subtract(cal1630StopHour).multiply(BigDecimal.valueOf(100)).divide(totalHour, 2, BigDecimal.ROUND_HALF_UP));
        list.add(w2);

        BigDecimal cal2150DurationSum = BigDecimal.ZERO;
        List<tbDowntimeCal2150> cal2150DownList = downTimeService.selectCal2150DownTimeMonth(startTime);
        for (tbDowntimeCal2150 down : cal2150DownList) {
            if (StringUtils.isEmpty(down.getStopEndTime())) continue;
            //处理跨月停机情况
            Calendar cal1 = Calendar.getInstance();
            Date startDate = DateUtil.getStringToDate("yyyy-MM-dd HH:mm:ss.SSS", down.getStopStartTime());
            cal1.setTime(startDate);
            int startMonth = cal1.get(Calendar.MONTH) + 1;
            Calendar cal2 = Calendar.getInstance();
            Date stopDate = DateUtil.getStringToDate("yyyy-MM-dd HH:mm:ss.SSS", down.getStopEndTime());
            cal2.setTime(stopDate);
            int endMonth = cal2.get(Calendar.MONTH) + 1;
            Integer duration = down.getDuration();
            //开始结束对应的日不等
            if (startMonth != endMonth) {
                //当日开始，下日结束
                if (month == startMonth) {
                    long timeInMillis2 = cal1.getTimeInMillis();
                    cal1.add(Calendar.DAY_OF_MONTH, 1);
                    cal1.set(Calendar.HOUR_OF_DAY, 0);
                    cal1.set(Calendar.MINUTE, 0);
                    cal1.set(Calendar.SECOND, 0);
                    cal1.set(Calendar.MILLISECOND, 0);
                    long difference = cal1.getTimeInMillis() - timeInMillis2;
                    duration = (int) (difference / 1000);
                } else {
                    long timeInMillis2 = cal2.getTimeInMillis();
                    cal2.set(Calendar.HOUR_OF_DAY, 0);
                    cal2.set(Calendar.MINUTE, 0);
                    cal2.set(Calendar.SECOND, 0);
                    cal2.set(Calendar.MILLISECOND, 0);
                    long difference = timeInMillis2 - cal2.getTimeInMillis();
                    duration = (int) (difference / 1000);
                }
            }
            cal2150DurationSum = cal2150DurationSum.add(BigDecimal.valueOf(duration));
        }
        BigDecimal cal2150StopHour = cal2150DurationSum.divide(BigDecimal.valueOf(3600), 1, BigDecimal.ROUND_HALF_UP);
        WorkRate w3 = new WorkRate();
        w3.setLineName("3#连退");
        w3.setStopHour(cal2150StopHour);
        w3.setTotalHour(totalHour);
        w3.setRate(totalHour.subtract(cal2150StopHour).multiply(BigDecimal.valueOf(100)).divide(totalHour, 2, BigDecimal.ROUND_HALF_UP));
        list.add(w3);

        BigDecimal cglDurationSum = BigDecimal.ZERO;
        List<tbDowntimeCgl1870> tbDowntimeCgl1870s = downTimeService.selectcglDownTimeMonth(startTime);
        for (tbDowntimeCgl1870 down : tbDowntimeCgl1870s) {
            //处理跨月停机情况
            Calendar cal1 = Calendar.getInstance();
            Date startDate = DateUtil.getStringToDate("yyyy-MM-dd HH:mm:ss.SSS", down.getStopStartTime());
            cal1.setTime(startDate);
            int startMonth = cal1.get(Calendar.MONTH) + 1;
            Calendar cal2 = Calendar.getInstance();
            Date stopDate = DateUtil.getStringToDate("yyyy-MM-dd HH:mm:ss.SSS", down.getStopEndTime());
            cal2.setTime(stopDate);
            int endMonth = cal2.get(Calendar.MONTH) + 1;
            Integer duration = down.getDuration();
            //开始结束对应的日不等
            if (startMonth != endMonth) {
                //当日开始，下日结束
                if (month == startMonth) {
                    long timeInMillis2 = cal1.getTimeInMillis();
                    cal1.add(Calendar.DAY_OF_MONTH, 1);
                    cal1.set(Calendar.HOUR_OF_DAY, 0);
                    cal1.set(Calendar.MINUTE, 0);
                    cal1.set(Calendar.SECOND, 0);
                    cal1.set(Calendar.MILLISECOND, 0);
                    long difference = cal1.getTimeInMillis() - timeInMillis2;
                    duration = (int) (difference / 1000);
                } else {
                    long timeInMillis2 = cal2.getTimeInMillis();
                    cal2.set(Calendar.HOUR_OF_DAY, 0);
                    cal2.set(Calendar.MINUTE, 0);
                    cal2.set(Calendar.SECOND, 0);
                    cal2.set(Calendar.MILLISECOND, 0);
                    long difference = timeInMillis2 - cal2.getTimeInMillis();
                    duration = (int) (difference / 1000);
                }
            }
            cglDurationSum = cglDurationSum.add(BigDecimal.valueOf(duration));
        }
        BigDecimal cglStopHour = cglDurationSum.divide(BigDecimal.valueOf(3600), 1, BigDecimal.ROUND_HALF_UP);

        WorkRate w4 = new WorkRate();
        w4.setLineName("5#镀锌");
        w4.setStopHour(cglStopHour);
        w4.setTotalHour(totalHour);
        w4.setRate(totalHour.subtract(cglStopHour).multiply(BigDecimal.valueOf(100)).divide(totalHour, 2, BigDecimal.ROUND_HALF_UP));
        list.add(w4);
        return ResultData.ResultDataSuccess(list, list.size());
    }

    @Override
    public ResultData tcmOutputCrew(OutputReq tc) {
        String startDate = DateUtil.getDateToString(DateUtil.getLastDayZero(new Date()), "yyyyMMdd");
        if (StringUtils.isNotEmpty(tc.getStartDate())) {
            startDate = tc.getStartDate();
        }
        List<OutputRes> resList = new ArrayList<>();
        OutputRes res1 = new OutputRes();
        OutputRes res2 = new OutputRes();
        OutputRes res3 = new OutputRes();

        //计划产量不从秒用时累加了
        LambdaQueryWrapper<RepTcmOutputPlanAct> w = new LambdaQueryWrapper<>();
        w.eq(RepTcmOutputPlanAct::getShijian, startDate).eq(RepTcmOutputPlanAct::getLineCode, "tcm2280");
        RepTcmOutputPlanAct targetObj = repPlanActService.getOne(w);
        res1.setTarget(targetObj.getDayPlan().divide(BigDecimal.valueOf(3), 2, RoundingMode.HALF_UP));
        res2.setTarget(targetObj.getDayPlan().multiply(BigDecimal.valueOf(11).divide(BigDecimal.valueOf(24), 2, RoundingMode.HALF_UP)));
        res3.setTarget(targetObj.getDayPlan().multiply(BigDecimal.valueOf(5).divide(BigDecimal.valueOf(24), 2, RoundingMode.HALF_UP)));

        LambdaQueryWrapper<RepTcmOutputHour> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RepTcmOutputHour::getShijian, startDate);
        List<RepTcmOutputHour> list = repOutputHourService.list(wrapper);
        for (RepTcmOutputHour re : list) {
            String crew = CommonConstant.crewMap.get(re.getBanzu());
            if (re.getHour() >= 0 && re.getHour() < 8) {
                if (StringUtils.isNotEmpty(crew)) res1.setCrew("0:00--8:00(" + crew + ")");
                res1.setActual(res1.getActual().add(re.getOutMatWt2()));
            } else if (re.getHour() >= 8 && re.getHour() < 19) {
                if (StringUtils.isNotEmpty(crew)) res2.setCrew("8:00--19:00(" + crew + ")");
                res2.setActual(res2.getActual().add(re.getOutMatWt2()));
            } else {
                if (StringUtils.isNotEmpty(crew)) res3.setCrew("19:00--24:00(" + crew + ")");
                res3.setActual(res3.getActual().add(re.getOutMatWt2()));
            }
        }
        res1.setOverNum(res1.getActual().subtract(res1.getTarget()).setScale(2, RoundingMode.HALF_UP));
        res1.setOverRate(res1.getActual().multiply(BigDecimal.valueOf(100)).divide(res1.getTarget(), 2, RoundingMode.HALF_UP));
        res2.setOverNum(res2.getActual().subtract(res2.getTarget()).setScale(2, RoundingMode.HALF_UP));
        res2.setOverRate(res2.getActual().multiply(BigDecimal.valueOf(100)).divide(res2.getTarget(), 2, RoundingMode.HALF_UP));
        res3.setOverNum(res3.getActual().subtract(res3.getTarget()).setScale(2, RoundingMode.HALF_UP));
        res3.setOverRate(res3.getActual().multiply(BigDecimal.valueOf(100)).divide(res3.getTarget(), 2, RoundingMode.HALF_UP));
        resList.add(res1);
        resList.add(res2);
        resList.add(res3);

        return ResultData.ResultDataSuccess(resList, resList.size());
    }

    @Override
    public ResultData tcmOutput(OutputReq tc) {
        String startDate = DateUtil.getDateToString(DateUtil.getLastDayZero(new Date()), "yyyyMMdd");
        String endDate = DateUtil.getDateToString(DateUtil.getCurrentZero(new Date()), "yyyyMMdd");
        if (StringUtils.isNotEmpty(tc.getStartDate())) {
            startDate = tc.getStartDate();
            Date d = DateUtil.getStringToDate("yyyyMMdd", startDate);
            Calendar cal = Calendar.getInstance();
            cal.setTime(d);
            cal.add(Calendar.DAY_OF_MONTH, 1);
            endDate = DateUtil.getDateToString(cal.getTime(), "yyyyMMdd");
        }
        TpdoL3 l3 = repOutputHourService.findL3Data2280(startDate, endDate);
        //计划产量不从秒用时累加了
        LambdaQueryWrapper<RepTcmOutputPlanAct> w = new LambdaQueryWrapper<>();
        w.eq(RepTcmOutputPlanAct::getShijian, startDate).eq(RepTcmOutputPlanAct::getLineCode, "tcm2280");
        RepTcmOutputPlanAct targetObj = repPlanActService.getOne(w);
        BigDecimal target = BigDecimal.ZERO;
        if (targetObj != null) {
            target = targetObj.getDayPlan();
        }
        OutputRes res = new OutputRes();
        res.setTarget(target);
        res.setActual(l3.getActual());
        res.setOverNum(res.getActual().subtract(res.getTarget()));
        BigDecimal rate = BigDecimal.ZERO;
        if (res.getTarget().compareTo(BigDecimal.ZERO) > 0) {
            rate = res.getActual().multiply(BigDecimal.valueOf(100)).divide(res.getTarget(), 2, RoundingMode.HALF_UP);
        }
        res.setOverRate(rate);

        return ResultData.ResultDataSuccess(res);
    }

    @Override
    public ResultData findData(String dateType) {
        List<TpdoL3TcmYield> list = new ArrayList<>();
        if ("day".equals(dateType)) {
            //当日产量
            LambdaQueryWrapper<RepOutput> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(RepOutput::getLineName, "tcm2280");
            RepOutput repOutput = repOutputService.getOne(wrapper);

            //当日计划
            LambdaQueryWrapper<RepTcmOutputHour> w = new LambdaQueryWrapper<>();
            w.eq(RepTcmOutputHour::getShijian, "0");
            RepTcmOutputHour output = repOutputHourService.getOne(w);

            TpdoL3TcmYield temp = new TpdoL3TcmYield();
            String today = DateUtil.getDateToString(new Date(), "yyyyMMdd");
            temp.setProdDate(today);
            temp.setTarget(mapper.selectXiada(today));
            temp.setActual(repOutput.getRichan());
            temp.setTargetRoll(output.getTargetRoll());
            temp.setActualRoll(repOutput.getActualRoll());
            temp.setAchi(temp.getActual().multiply(BigDecimal.valueOf(100)).divide(temp.getTarget(), 2, RoundingMode.HALF_UP));
            list.add(temp);

            //10日内的统计数据
            String endDate = DateUtil.getDateToString(DateUtil.getBeforDate(), "yyyyMMdd");
            list.addAll(mapper.findData(tenDaysAgo(), endDate));
            for (int i = 0; i < list.size(); i++) {
                TpdoL3TcmYield t = list.get(i);
                Date d = DateUtil.getStringToDate("yyyyMMdd", t.getProdDate());
                t.setProdDate(DateUtil.getDateToString(d, "MM/dd"));
            }
        } else {
            //其他情况按小时，显示10小时内数据
            list = mapper.findHourData(10);
            for (TpdoL3TcmYield t : list) {
                t.setProdDate(t.getProdDate() + ":00");
            }
        }
        Collections.reverse(list);
        return ResultData.ResultDataSuccess(list, list.size());
    }

    @Override
    public ResultData<TcmNoPlanStopRes> findNonHaltData(TPdoL3TcmBaseRequest req) {
        String dateType = req.getDateType();

        TcmNoPlanStopRes l3 = new TcmNoPlanStopRes();
        List<String> shijianList = new ArrayList<>();
        List<Integer> dursumList = new ArrayList<>();
        List<Integer> prodsumList = new ArrayList<>();
        List<Integer> equsumList = new ArrayList<>();
        List<Integer> elssumList = new ArrayList<>();

        //默认月初时间
        String startDay = tenDaysAgo("yyyy-MM-dd");
        String endDay = nextMonthFirstDay("yyyy-MM-01");
        if ("day".equals(dateType)) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            Date current = cal.getTime();
            cal.setTime(DateUtil.getStringToDate("yyyy-MM-dd", startDay));
            while (cal.getTime().before(current)) {
                shijianList.add((cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DAY_OF_MONTH));
                prodsumList.add(0);
                equsumList.add(0);
                elssumList.add(0);
                dursumList.add(0);
                cal.add(Calendar.DAY_OF_MONTH, 1);
            }
        } else if ("month".equals(dateType)) {
            //年初时间
            startDay = DateUtil.getDateToString(new Date(), "yyyy-01-01");
            Calendar cal = Calendar.getInstance();
            int month = cal.get(Calendar.MONTH) + 1;
            for (int i = 1; i <= month; i++) {
                shijianList.add(i + "月");
                prodsumList.add(0);
                equsumList.add(0);
                elssumList.add(0);
                dursumList.add(0);
            }
        } else if ("week".equals(dateType)) {
            //暂定起始日期为当前周加上前8周
            int totalWeek = 8;
            Calendar cal = new GregorianCalendar();
            cal.setFirstDayOfWeek(Calendar.MONDAY);
            cal.setTime(new Date());
            cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
            cal.add(Calendar.DAY_OF_MONTH, -totalWeek * 7);//前四周
            Date firstDay = cal.getTime();
            startDay = DateUtil.getDateToString(firstDay, "yyyy-MM-dd");

            for (int i = 0; i < totalWeek; i++) {
                String s1 = (cal.get(Calendar.MONTH) + 1) + "/" + (cal.get(Calendar.DAY_OF_MONTH)) + "-";
                cal.add(Calendar.DAY_OF_MONTH, 6);
                String s2 = (cal.get(Calendar.MONTH) + 1) + "/" + (cal.get(Calendar.DAY_OF_MONTH));
                shijianList.add(s1 + s2);
                prodsumList.add(0);
                equsumList.add(0);
                elssumList.add(0);
                dursumList.add(0);
                cal.add(Calendar.DAY_OF_MONTH, 1);
            }

            shijianList.add((cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DAY_OF_MONTH) + "--");
            prodsumList.add(0);
            equsumList.add(0);
            elssumList.add(0);
            dursumList.add(0);
        }

        List<TbDowntimeTcm2280Dto> list = downTimeService.getTbDowntimeTcm2280List(startDay, endDay);
        for (TbDowntimeTcm2280Dto t : list) {
            String stopStartTime = t.getStopStartTime();
            int stopType = checkout(t.getStopB());
            Date d = DateUtil.getStringToDate("yyyy-MM-dd", stopStartTime);
            Calendar cal = Calendar.getInstance();
            cal.setTime(d);
            cal.setFirstDayOfWeek(Calendar.MONDAY);
            String m = null;
            if ("month".equals(dateType)) {
                m = (cal.get(Calendar.MONTH) + 1) + "月";
            } else if ("day".equals(dateType)) {
                m = (cal.get(Calendar.MONTH) + 1) + "月" + (cal.get(Calendar.DAY_OF_MONTH)) + "日";
            } else {
                cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
                m = (cal.get(Calendar.MONTH) + 1) + "月" + (cal.get(Calendar.DAY_OF_MONTH)) + "日";
            }
            for (int i = 0; i < shijianList.size(); i++) {
                if (shijianList.get(i).startsWith(m)) {
                    dursumList.set(i, dursumList.get(i) + t.getDuration());
                    switch (stopType) {
                        case 1:
                            prodsumList.set(i, prodsumList.get(i) + t.getDuration());
                            break;
                        case 2:
                            equsumList.set(i, equsumList.get(i) + t.getDuration());
                            break;
                        case 3:
                            elssumList.set(i, elssumList.get(i) + t.getDuration());
                            break;
                    }
                    break;
                }
            }
        }

        l3.setShijian(shijianList);
        l3.setDursum(dursumList);
        l3.setProdsum(prodsumList);
        l3.setEqusum(equsumList);
        l3.setElssum(elssumList);

        return ResultData.ResultDataSuccess(l3);
    }

    private int checkout(String str) {
        //生产故障
        String[] arr1 = new String[]{"生产准备-换工作辊(非计划)", "生产准备-工艺调整", "生产准备-其它", "生产故障"};
        for (int i = 0; i < arr1.length; i++) {
            if (str.equals(arr1[i])) {
                return 1;
            }
        }
        //设备故障
        String[] arr2 = new String[]{"机械故障", "电气故障", "轧辊故障", "停机点检-机械", "停机点检-电气"};
        for (int i = 0; i < arr2.length; i++) {
            if (str.equals(arr2[i])) {
                return 2;
            }
        }
        //其他故障
        String[] arr3 = new String[]{"待料", "其它-能源介质", "其它-外部因素", "能介故障"};
        for (int i = 0; i < arr3.length; i++) {
            if (str.equals(arr3[i])) {
                return 3;
            }
        }
        return -1;
    }

    @Override
    public ResultData<TpdoL3Res> findCrewAchiData(TPdoL3CrewARequest req) {
        TpdoL3Res l3 = new TpdoL3Res();

        String dateType = req.getDateType();
        String startDay = null;
        String endDay = nextMonthFirstDay();
        if ("day".equals(dateType)) {
            startDay = tenDaysAgo();
        } else if ("month".equals(dateType)) {
            startDay = DateUtil.getDateToString(new Date(), "yyyy0101");
        }
        List<TpdoL3> list = mapper.findCrewAchiData(dateType, req.getCrew(), startDay, endDay);

        List<String> clist = new ArrayList<>();
        List<BigDecimal> tarList = new ArrayList<>();
        List<BigDecimal> actList = new ArrayList<>();
        List<BigDecimal> achiList = new ArrayList<>();
        for (TpdoL3 crew : list) {
            String s = crew.getShijian();
            String shijian = "";
            if ("day".equals(dateType)) {
                Date d = DateUtil.getStringToDate("yyyyMMdd", s);
                shijian = DateUtil.getDateToString(d, "MM/dd");
            } else if ("month".equals(dateType)) {
                Date d = DateUtil.getStringToDate("yyyyMM", s);
                shijian = DateUtil.getDateToString(d, "yyyy/MM");
            }
            clist.add(shijian);
            tarList.add(crew.getTarget());
            actList.add(crew.getActual());
            achiList.add(crew.getAchi());
        }
        l3.setCategory(clist);
        l3.setTarget(tarList);
        l3.setActual(actList);
        l3.setAchi(achiList);

        return ResultData.ResultDataSuccess(l3);
    }

    @Override
    public ResultData<TpdoL3Res> findModulesData(TPdoL3TcmRequest req) {
        String dateType = req.getDateType();//日期分类标识
        //TODO week暂不支持
        if ("week".equals(dateType)) {
            dateType = "day";
        }

        String startDay = tenDaysAgo();
        if ("month".equals(dateType)) {
            startDay = DateUtil.getDateToString(new Date(), "yyyy0101");
        }

        TpdoL3Res l3 = new TpdoL3Res();
        List<String> clist = new ArrayList<>();
        List<BigDecimal> tarList = new ArrayList<>();
        List<BigDecimal> actList = new ArrayList<>();
        List<BigDecimal> achiList = new ArrayList<>();
        List<TpdoL3TcmYield> list = mapper.findYield2280ByDayData(dateType, startDay, nextMonthFirstDay());
        for (TpdoL3TcmYield yield : list) {
            if ("day".equals(dateType)) {
                Date d = DateUtil.getStringToDate("yyyyMMdd", yield.getProdDate());
                clist.add(DateUtil.getDateToString(d, "MM/dd"));
                tarList.add(yield.getTarget());
                actList.add(yield.getActual());
                achiList.add(yield.getActual().divide(yield.getTarget(), 4, BigDecimal.ROUND_HALF_UP));
            } else if ("month".equals(dateType)) {
                Date d = DateUtil.getStringToDate("yyyyMM", yield.getProdDate());
                clist.add(DateUtil.getDateToString(d, "MM月"));
                tarList.add(yield.getTarget());
                actList.add(yield.getActual());
                achiList.add(yield.getActual().divide(yield.getTarget(), 4, BigDecimal.ROUND_HALF_UP));
            }
        }
        l3.setCategory(clist);
        l3.setTarget(tarList);
        l3.setActual(actList);
        l3.setAchi(achiList);

        return ResultData.ResultDataSuccess(l3);
    }
}